import 'dart:convert';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';

void main() {
  // 真实的测试数据
  const originalData = '{"appid":1004,"from":3,"uid":"","utoken":""}';
  const expectedEncrypted = 'omeAKfdkAgpOyVm4TtFbjGPI9DsTkTnf+U0QRI6JI9QjBe9fOqtoJR165EUP6qOY/FTxleDXDH3nR4+VQYrhGg==';
  
  // 真实的密钥和IV
  const realKey = 'pTDypRAn8xfEA0lSjtE5TeGuObzaYMMb';
  const realIV = 'pTYwUr3tdh08uXBb';
  
  print('=== 测试JSON序列化差异 ===');
  
  // 分析JSON序列化差异
  analyzeJSONDifferences(originalData, realKey, realIV, expectedEncrypted);
}

void analyzeJSONDifferences(String originalData, String key, String iv, String expected) {
  print('原始数据: $originalData');
  
  // 解析JSON
  final jsonData = jsonDecode(originalData);
  print('解析的JSON: $jsonData');
  
  // 检查数据类型
  print('appid类型: ${jsonData['appid'].runtimeType}');
  print('from类型: ${jsonData['from'].runtimeType}');
  print('uid类型: ${jsonData['uid'].runtimeType}');
  print('utoken类型: ${jsonData['utoken'].runtimeType}');
  
  // 尝试不同的JSON序列化方式
  final jsonString1 = jsonEncode(jsonData);
  print('\n标准JSON序列化: $jsonString1');
  print('标准序列化长度: ${utf8.encode(jsonString1).length}');
  
  // 检查是否有差异
  print('与原始数据匹配: ${jsonString1 == originalData}');
  
  if (jsonString1 != originalData) {
    print('⚠️ JSON序列化有差异！');
    
    // 分析差异
    for (int i = 0; i < math.min(originalData.length, jsonString1.length); i++) {
      if (originalData[i] != jsonString1[i]) {
        print('第一个差异位置: $i');
        print('原始字符: "${originalData[i]}" (ASCII: ${originalData.codeUnitAt(i)})');
        print('序列化字符: "${jsonString1[i]}" (ASCII: ${jsonString1.codeUnitAt(i)})');
        break;
      }
    }
    
    if (originalData.length != jsonString1.length) {
      print('长度差异: 原始=${originalData.length}, 序列化=${jsonString1.length}');
    }
  }
  
  // 尝试使用不同的数据类型
  print('\n=== 测试不同的数据类型 ===');
  
  // 测试1: 数字作为字符串
  final jsonData2 = {
    'appid': '1004',
    'from': '3',
    'uid': '',
    'utoken': ''
  };
  final jsonString2 = jsonEncode(jsonData2);
  print('数字作为字符串: $jsonString2');
  print('长度: ${utf8.encode(jsonString2).length}');
  
  // 测试2: 数字作为整数
  final jsonData3 = {
    'appid': 1004,
    'from': 3,
    'uid': '',
    'utoken': ''
  };
  final jsonString3 = jsonEncode(jsonData3);
  print('数字作为整数: $jsonString3');
  print('长度: ${utf8.encode(jsonString3).length}');
  
  // 测试3: 空字符串的不同表示
  final jsonData4 = {
    'appid': 1004,
    'from': 3,
    'uid': null,
    'utoken': null
  };
  final jsonString4 = jsonEncode(jsonData4);
  print('空值作为null: $jsonString4');
  print('长度: ${utf8.encode(jsonString4).length}');
  
  // 现在测试加密
  print('\n=== 测试不同JSON序列化的加密结果 ===');
  
  final testCases = [
    originalData,
    jsonString1,
    jsonString2,
    jsonString3,
    jsonString4,
  ];
  
  for (int i = 0; i < testCases.length; i++) {
    final testData = testCases[i];
    print('\n测试 ${i + 1}: ${getTestDescription(i)}');
    print('数据: $testData');
    print('长度: ${utf8.encode(testData).length}');
    
    try {
      final result = encryptData(testData, key, iv);
      print('加密结果: $result');
      print('匹配: ${result == expected ? "✅ 找到匹配！" : "❌"}');
      
      if (result == expected) {
        print('🎉 成功！正确的JSON序列化方式是：${getTestDescription(i)}');
        return;
      }
      
    } catch (e) {
      print('错误: $e');
    }
  }
  
  print('\n所有JSON序列化方式都未找到匹配...');
}

String getTestDescription(int index) {
  switch (index) {
    case 0: return '原始数据';
    case 1: return '标准JSON序列化';
    case 2: return '数字作为字符串';
    case 3: return '数字作为整数';
    case 4: return '空值作为null';
    default: return '未知';
  }
}

String encryptData(String data, String key, String iv) {
  final keyBytes = utf8.encode(key);
  final ivBytes = utf8.encode(iv);
  
  // 处理密钥和IV（模拟OC的setLength行为）
  const keySize = 32;
  
  final processedKey = Uint8List(keySize);
  for (int i = 0; i < keySize; i++) {
    if (i < keyBytes.length) {
      processedKey[i] = keyBytes[i];
    } else {
      processedKey[i] = 0;
    }
  }
  
  final processedIV = Uint8List(keySize);
  for (int i = 0; i < keySize; i++) {
    if (i < ivBytes.length) {
      processedIV[i] = ivBytes[i];
    } else {
      processedIV[i] = 0;
    }
  }
  
  // 只使用IV的前16字节
  final actualIV = processedIV.sublist(0, 16);
  
  final keyObj = Key(processedKey);
  final ivObj = IV(actualIV);
  final encrypter = Encrypter(AES(keyObj, mode: AESMode.cbc));
  
  final encrypted = encrypter.encrypt(data, iv: ivObj);
  return encrypted.base64;
}
